﻿namespace FiftyOne.Foundation.Mobile.Detection.Wurfl.Matchers.EditDistance
{
    using FiftyOne.Foundation.Mobile.Detection.Wurfl;
    using FiftyOne.Foundation.Mobile.Detection.Wurfl.Handlers;
    using FiftyOne.Foundation.Mobile.Detection.Wurfl.Matchers;
    using System;
    using System.Threading;

    internal class Matcher : FiftyOne.Foundation.Mobile.Detection.Wurfl.Matchers.Matcher
    {
        internal static FiftyOne.Foundation.Mobile.Detection.Wurfl.Matchers.EditDistance.Results Match(string userAgent, Handler handler)
        {
            if (Environment.ProcessorCount > 1)
            {
                return MatchMultiProcessor(userAgent, handler);
            }
            return MatchSingleProcessor(userAgent, handler);
        }

        private static FiftyOne.Foundation.Mobile.Detection.Wurfl.Matchers.EditDistance.Results MatchMultiProcessor(string userAgent, Handler handler)
        {
            AutoResetEvent completeEvent = new AutoResetEvent(false);
            FiftyOne.Foundation.Mobile.Detection.Wurfl.Matchers.EditDistance.Request state = new FiftyOne.Foundation.Mobile.Detection.Wurfl.Matchers.EditDistance.Request(userAgent, handler, completeEvent);
            if (state.Count > 0)
            {
                for (int i = 0; i < Environment.ProcessorCount; i++)
                {
                    ThreadPool.QueueUserWorkItem(new WaitCallback(FiftyOne.Foundation.Mobile.Detection.Wurfl.Matchers.EditDistance.Matcher.ServiceRequest), state);
                }
                while (!completeEvent.WaitOne(1, false))
                {
                }
            }
            return state.Results;
        }

        private static FiftyOne.Foundation.Mobile.Detection.Wurfl.Matchers.EditDistance.Results MatchSingleProcessor(string userAgent, Handler handler)
        {
            FiftyOne.Foundation.Mobile.Detection.Wurfl.Matchers.EditDistance.Request request = new FiftyOne.Foundation.Mobile.Detection.Wurfl.Matchers.EditDistance.Request(userAgent, handler);
            ServiceRequest(request);
            return request.Results;
        }

        private static void ServiceRequest(FiftyOne.Foundation.Mobile.Detection.Wurfl.Matchers.EditDistance.Request request)
        {
            string userAgent = request.UserAgent;
            DeviceInfo device = request.Next();
            while (device != null)
            {
                int num = Algorithms.EditDistance(device.UserAgent, userAgent, request.Results.MinDistance);
                if (num <= request.Results.MinDistance)
                {
                    lock (request.Results)
                    {
                        if (num < request.Results.MinDistance)
                        {
                            request.Results.MinDistance = num;
                            request.Results.Clear();
                            request.Results.Add(device);
                        }
                        else if (num == request.Results.MinDistance)
                        {
                            request.Results.Add(device);
                        }
                    }
                }
                device = request.Next();
                request.Complete();
            }
        }

        private static void ServiceRequest(object sender)
        {
            ServiceRequest((FiftyOne.Foundation.Mobile.Detection.Wurfl.Matchers.EditDistance.Request) sender);
        }
    }
}

